﻿using DVM.DV.Extensions;
using DVM.DV.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace DVM.DV
{
    public interface IDMContext
    {
        /// <summary>
        /// 为输出对象属性赋值
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="outPutObj">输出对象</param>
        /// <param name="propertyInfo">属性</param>
        /// <param name="sourceValue">属性值</param>
        public void SetValue<TResult>(TResult outPutObj, PropertyInfo? propertyInfo, object sourceValue) where TResult : class, new();
    }


    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="TSource"></typeparam>
    /// <typeparam name="TView"></typeparam>
    public abstract class DVContext<TSource, TView> : IDMContext
            where TSource : notnull
            where TView : class

    {
        /// <summary>
        /// 字段属性名称
        /// </summary>
        public virtual string FieldName()
        {
            var fieldAttribute = GetType().GetCustomAttribute(typeof(PropertySetAttribute));
            var fieldName = fieldAttribute == null ? string.Empty : ((PropertySetAttribute)fieldAttribute).SetPropertyName;
            return InitInfo.SourcePropertyInfos.FirstOrDefault(x => x.Value.PropertySetName == fieldName).Key ?? string.Empty;
        }

        /// <summary>
        /// 字段属性对应基础信息
        /// </summary>
        public InitInfo InitInfo { get; set; }

        public DVContext(InitInfo initInfo)
        {
            InitInfo = initInfo;
            QueryViewResult = ConvertView();
        }

        /// <summary>
        /// 转化key值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public TSource ConvertKey(object key)
        {
            return (TSource)key;
        }



        /// <summary>
        /// 获取属性值
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        public List<TSource> GetPropertyValue()
        {
            var fieldName = FieldName();
            if (fieldName == string.Empty)
            {
                throw new Exception("未能找到对应的字段名称");
            }
            return InitInfo.SourcePropertyInfos[fieldName].FieldValue.Select(x => (TSource)x).ToList();
        }




        /// <summary>
        /// 构建基础查询
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="source"></param>
        /// <returns></returns>
        public abstract Dictionary<TSource, TView> ConvertView();

        /// <summary>
        /// 用于存放查询执行结果
        /// </summary>
        public Dictionary<TSource, TView> QueryViewResult { get; set; }
        

        public void SetValue<TResult>(TResult outPutObj, PropertyInfo? propertyInfo, object sourceValue)
           where TResult : class, new()
        {
            if (QueryViewResult == null || !QueryViewResult.Any())
                return;
            var key = ConvertKey(sourceValue);
            if (propertyInfo != null)
                propertyInfo.SetValue(outPutObj, QueryViewResult[key]);
        }
    }
}
